<template>
  <div class="optimized-image-container" :class="{ loading: isLoading }">
    <img
      ref="imageRef"
      :src="currentSrc"
      :alt="alt"
      :class="imageClass"
      @load="handleLoad"
      @error="handleError"
      v-bind="$attrs"
    />
    
    <!-- 加载占位符 -->
    <div v-if="isLoading" class="image-placeholder">
      <div class="placeholder-content">
        <el-icon class="loading-icon"><Loading /></el-icon>
        <span>加载中...</span>
      </div>
    </div>
    
    <!-- 错误占位符 -->
    <div v-if="hasError" class="image-error">
      <div class="error-content">
        <el-icon class="error-icon"><Picture /></el-icon>
        <span>图片加载失败</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { Loading, Picture } from '@element-plus/icons-vue'
import { getOptimizedImageUrl, supportsWebP, lazyLoader } from '@/utils/imageOptimization'

const props = defineProps({
  src: {
    type: String,
    required: true
  },
  alt: {
    type: String,
    default: ''
  },
  lazy: {
    type: Boolean,
    default: true
  },
  width: {
    type: [Number, String],
    default: null
  },
  height: {
    type: [Number, String],
    default: null
  },
  quality: {
    type: Number,
    default: 80
  },
  placeholder: {
    type: String,
    default: ''
  },
  webp: {
    type: Boolean,
    default: true
  },
  compress: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['load', 'error'])

const imageRef = ref(null)
const isLoading = ref(true)
const hasError = ref(false)
const isWebPSupported = ref(false)
const currentSrc = ref('')

// 计算优化后的图片URL
const optimizedSrc = computed(() => {
  if (!props.src) return ''
  
  const options = {
    width: props.width,
    height: props.height,
    quality: props.quality
  }
  
  // 如果支持WebP且启用WebP优化
  if (isWebPSupported.value && props.webp) {
    options.format = 'webp'
  }
  
  return props.compress ? getOptimizedImageUrl(props.src, options) : props.src
})

// 图片类名
const imageClass = computed(() => {
  return {
    'optimized-image': true,
    'loaded': !isLoading.value && !hasError.value,
    'error': hasError.value
  }
})

// 处理图片加载完成
const handleLoad = () => {
  isLoading.value = false
  hasError.value = false
  emit('load')
}

// 处理图片加载错误
const handleError = () => {
  isLoading.value = false
  hasError.value = true
  emit('error')
}

// 初始化图片
const initImage = () => {
  if (!props.src) return
  
  isLoading.value = true
  hasError.value = false
  
  if (props.lazy) {
    // 懒加载模式
    currentSrc.value = props.placeholder
    if (imageRef.value) {
      imageRef.value.dataset.src = optimizedSrc.value
      lazyLoader.observe(imageRef.value)
    }
  } else {
    // 立即加载
    currentSrc.value = optimizedSrc.value
  }
}

// 监听src变化
watch(() => props.src, () => {
  initImage()
}, { immediate: false })

// 监听优化后的src变化
watch(optimizedSrc, (newSrc) => {
  if (!props.lazy) {
    currentSrc.value = newSrc
  }
})

onMounted(async () => {
  // 检查WebP支持
  isWebPSupported.value = await supportsWebP()
  
  // 初始化图片
  initImage()
})

onUnmounted(() => {
  if (imageRef.value && props.lazy) {
    lazyLoader.unobserve(imageRef.value)
  }
})
</script>

<style scoped>
.optimized-image-container {
  position: relative;
  display: inline-block;
  overflow: hidden;
}

.optimized-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.3s ease;
  opacity: 0;
}

.optimized-image.loaded {
  opacity: 1;
}

.optimized-image.error {
  opacity: 0;
}

.image-placeholder,
.image-error {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  border: 1px dashed #dcdfe6;
}

.placeholder-content,
.error-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: #909399;
  font-size: 14px;
}

.loading-icon {
  font-size: 24px;
  animation: rotate 1s linear infinite;
}

.error-icon {
  font-size: 24px;
  color: #f56c6c;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* 响应式优化 */
@media (max-width: 768px) {
  .placeholder-content,
  .error-content {
    font-size: 12px;
  }
  
  .loading-icon,
  .error-icon {
    font-size: 20px;
  }
}
</style>